import React from 'react'
import ReactDOM from 'react-dom'
import { Panel, PanelBody, LoadMore } from 'react-weui'
import axios from 'axios'

import config from '../../config.js'

import MessageItem from '../MessageItem/'

export default class MessageList extends React.Component {

  constructor(props) {
    super(props)

    this.state = {
      page: {},
      messages: []
    }

    this.ticking = false
    this.threshold = 20
  }

  componentDidMount() {
    // request messages
    axios.get(`${config.host}/contacters/${this.props.params.id}/messages`)
      .then(response => {
        let result = response.data
        if (parseInt(result.code) === 0) {
          this.setState((prevState, props) => ({
            page: result.data.page,
            messages: prevState.messages.concat(result.data.messages)
          }))
        }
      })

    // add scroll handler
    let root = ReactDOM.findDOMNode(this)
    this.loading = root.querySelector('#loading')
    window.addEventListener('scroll', this.requestScroll.bind(this))
  }

  requestScroll() {
    this.prevLoc = window.scrollY || window.pageYOffset
    this.requestFrame()
  }

  requestFrame() {
    if (!this.ticking) {
      window.requestAnimationFrame(() => this.check())
      this.ticking = true
    }
  }

  check() {
    if (this.inViewport(this.loading)) {
      this.requestNextPage()
    }
    this.ticking = false
  }

  inViewport(node) {
    const viewTop = this.prevLoc
    const viewBot = viewTop + window.innerHeight

    const nodeTop = node.getBoundingClientRect().top + this.prevLoc
    const nodeBot = nodeTop + node.offsetHeight

    const offset = (this.threshold / 100) * window.innerHeight
    return (nodeBot >= viewTop - offset) && (nodeTop <= viewBot + offset)
  }

  requestNextPage() {
    if (!this.requesting) {
      if (this.state.page.nextPages) {
        this.requesting = true
        axios.get(`${config.host}/contacters/${this.props.params.id}/messages?page=${this.state.page.currentPage + 1}`)
          .then(response => {
            let result = response.data
            if (parseInt(result.code) === 0) {
              this.setState((prevState, props) => ({
                page: result.data.page,
                messages: prevState.messages.concat(result.data.messages)
              }))
            }

            this.requesting = false
          })
          .catch(error => {
            this.requesting = false
            console.error(error)
          })
      }
    }
  }

  render() {
    return (
      <Panel>
        <PanelBody>
          {
            this.state.messages &&
              this.state.messages.map(message => {
                return (
                  <MessageItem message={ message } key={ message.id } />
                )
              })
          }
          {
            this.state.page.nextPage ?
              (<LoadMore loading id="loading">Loading</LoadMore> ) :
              (<LoadMore showLine id="loading">No data</LoadMore>)
          }
        </PanelBody>
      </Panel>
    )
  }

}